<template>
    <div class="box-container" ref="containerRef">
        <input 
            ref="inputRef"
            :class="['input-number', (border?'input-border':''), (disabled?'disable-btn':'')]"
            type="text"
            :disabled="disabled"
            :placeholder="placeholder"
            @input="inputHandle($event)"
            @blur="blurHandle($event)"
            @change="handleChange"
            @focus="handleFocus"
            :style="
                (controls?'padding-right: 40px;':'') + 
                ('height:' + height +'px;')  + 
                ('width:' + width + 'px;') 
            "
        />
        <div class="transfer-input" :style="`left:calc(${width} - ${suffixbg?'80':'40'}px);`" v-if="controls">
            <div class="btn-box">
                <span 
                    @click="addHandle" 
                    @mousedown="addMouseDown" 
                    @mouseup="addMouseout" 
                    @mouseout="addMouseout"
                    :class="[(max<=currentValue) || disabled?'disable-btn':'']"
                    :style="('height:' + (height / 2 - 1) + 'px;') + (suffixbg?'border-right: 1px solid #DCDFE6;':'')"
                >
                    <i class="el-icon-arrow-up"></i>
                </span>
                <span 
                    @click="subHandle" 
                    @mousedown="subMouseDown" 
                    @mouseup="subMouseout" 
                    @mouseout="subMouseout"
                    :class="[(min>=currentValue) || disabled?'disable-btn':'']"
                    :style="('height:' + (height / 2 - 1) + 'px;') + (suffixbg?'border-right: 1px solid #DCDFE6;':'')"
                >
                    <i class="el-icon-arrow-down"></i>
                </span>
            </div>
        </div>
        <div class="transfer-input" :style="`left:calc(${width} - 40px)`">
            <div :class="['suffix-box', (suffixbg?'suffix-box-bg':'')]">
                <slot name="suffix"></slot>
            </div>
        </div>
    </div>
</template>

<script>
import emitter from 'element-ui/lib/mixins/emitter';
import migrating from 'element-ui/lib/mixins/migrating';

export default {
    model:{
        prop: 'value',
        event: 'update:input'
    },
    inject: {
      elForm: {
        default: ''
      },
      elFormItem: {
        default: ''
      }
    },
    mixins:[emitter, migrating],
    props:{
        value:{},
        disabled:{
            type:Boolean,
            default:false
        },
        bitNumber:{
            type:Number,
            default:0,
        },
        max:{
            type:Number,
            default:9999999999,
        },
        min:{
            type:Number,
            default:-9999999999,
        },
        placeholder:{
            type:String,
            default:""
        },
        controls:{
            type: Boolean,
            default: true,
        },
        border:{
            type: Boolean,
            default: true,
        },
        suffixbg:{
            type: Boolean,
            default: false,
        }
    },
    created(){
        
    },
    watch: {
      value: {
        immediate: true,
        handler(newValue) {
            let newVal = newValue
            if(newVal === undefined||newVal === null){
                newVal = ''
            }
            this.currentValue = newVal;
            this.updateValueHandle(newVal, true)
            this.$nextTick(()=>{
                if(this.$refs.inputRef)this.$refs.inputRef.value = this.currentValue
            })
        }
      }
    },
    mounted(){
        this.resizeElement()
        window.addEventListener('resize', this.resizeHandle)
    },
    beforeDestroy(){
        window.removeEventListener('resize', this.resizeHandle)
    },
    data() {
        return {
            width:0,
            height:40,
            subTimer:null,
            currentValue:'',
        }
    },
    methods:{
        updateValueHandle(value, noCheck=false){
            this.$emit('update:input', value)
            if(!noCheck)this.dispatch("ElFormItem", 'el.form.change', [value])
        },
        inputHandle(event){
            this.currentValue = this.changeNumber(event)
            this.updateValueHandle(this.currentValue)
        },
        blurHandle(event){
            this.$emit('blur', event);
            let value = this.currentValue
            if(typeof value == 'string'){
                value = value.replace(/[^0-9.-]/ig, "")
            }
            if(value === ''){
                this.currentValue = ''
                this.updateValueHandle(this.currentValue)
                this.$nextTick(()=>{
                    if(this.$refs.inputRef)this.$refs.inputRef.value = this.currentValue
                })
                return
            }
            if(!value&&!this.currentValue&&(value!==0||value!=='0')){
                if(isNaN(event.target.value*1)){
                    this.currentValue = 0
                    this.updateValueHandle(this.currentValue)
                    this.$nextTick(()=>{
                        if(this.$refs.inputRef)this.$refs.inputRef.value = this.currentValue
                    })
                    return
                }
                if(event.target.value.trim() == ''){
                    this.currentValue = ''
                    this.updateValueHandle(this.currentValue)
                    this.$nextTick(()=>{
                        if(this.$refs.inputRef)this.$refs.inputRef.value = this.currentValue
                    })
                    return
                }
                return
            }
            if(value.includes&&value.includes('-')&&value.length==1){
                this.currentValue = ''
                this.updateValueHandle(this.currentValue)
                this.$nextTick(()=>{
                    if(this.$refs.inputRef)this.$refs.inputRef.value = this.currentValue
                })
                return
            }
            if(value>this.$props.max){
                this.currentValue = this.$props.max
                this.updateValueHandle(this.currentValue)
            }
            if(value<this.$props.min){
                this.currentValue = this.$props.min
                this.updateValueHandle(this.currentValue)
            }
            
            if(value[value.length-1] == '.'){
                this.currentValue = ((value !== 0 || value !== "0" ) && !value)? '' : value.slice(0, -1) * 1 
                this.updateValueHandle(this.currentValue)
            }else{
                this.currentValue = ((value !== 0 || value !== "0" ) && !value)? '' : value * 1 
                this.updateValueHandle(this.currentValue)
            }
            this.$nextTick(()=>{
                if(this.$refs.inputRef)this.$refs.inputRef.value = this.currentValue
            })
        },
        handleChange(event) {
            this.$emit('change', event.target.value);
        },
        handleFocus(event) {
            this.$emit('focus', event);
        },
        addHandle(){
            if(this.currentValue >= this.$props.max || this.$props.disabled){
                return
            }
            this.currentValue = (this.currentValue * 1) + 1
            this.updateValueHandle(this.currentValue)
            this.$nextTick(()=>{
                if(this.$refs.inputRef)this.$refs.inputRef.value = this.currentValue
            })
        },
        subHandle(){
            if(this.currentValue <= this.$props.min || this.$props.disabled){
                return
            }
            this.currentValue = this.currentValue - 1
            this.updateValueHandle(this.currentValue)
            this.$nextTick(()=>{
                if(this.$refs.inputRef)this.$refs.inputRef.value = this.currentValue
            })
        },
        subMouseDown(){
            if(!this.subTimer){
                this.subTimer = setInterval(()=>{
                    this.subHandle()
                },100)
            }
        },
        subMouseout(){
            if(this.subTimer){
                clearInterval(this.subTimer)
                this.subTimer = null
            }
        },
        addMouseDown(){
            if(!this.subTimer){
                this.subTimer = setInterval(()=>{
                    this.addHandle()
                },100)
            }
        },
        addMouseout(){
            if(this.subTimer){
                clearInterval(this.subTimer)
                this.subTimer = null
            }
        },
        resizeHandle(){
            this.resizeElement()
        },
        resizeElement(){
            if(this.$refs.containerRef.style.width || this.$refs.containerRef.offsetWidth < 180){
                if(this.$refs.containerRef.style.width.includes('%')){
                    this.width = '100%'
                }else{
                    this.width = this.$refs.containerRef.style.width
                }
            }else{
                this.width = '180px'
            }
            this.$refs.inputRef.style.width = this.width

            if(this.$refs.containerRef.style.height&&!this.$refs.containerRef.style.height.includes('%')){
                this.height = this.$refs.containerRef.style.height.replace('px','')
            }
            this.$refs.inputRef.style.height = this.height

            this.setElementStyle()
        },
        setElementStyle(){
            let textAlign = this.$refs.containerRef.style.textAlign
            this.$refs.inputRef.style.textAlign = textAlign
            if(textAlign&&textAlign != 'center'){
                this.$refs.inputRef.style.textIndent = textAlign=='start'?'10px':'50px'
            }
        },
        changeNumber(event, bitNumber=this.$props.bitNumber , max=this.$props.max, min=this.$props.min,){
            let bit = ((max+'').split('.')[0]).length
            let value = event.target.value
            value = value.replace(/[^0-9.-]/ig, "")
            if(value.includes('-')){
                value = "-" + value.replaceAll("-", "")
            }
            if(!value){
                if(value===0||value==='0'){
                    return 0
                }else{
                    return ''
                }
            }
            if( (value+'').includes('+') ){
                value = (value+'').replace('.','')
            }
            value = (value+'').replaceAll('+','')
            value = (value+'').replaceAll('e','')
            if(value.includes('.')){
                let arr = value.split('.')
                arr[0] = arr[0].slice(0,value.includes('-')?(bit+1):bit)
                arr[1] = arr[1].slice(0,bitNumber)
                value = (arr[0]||0) + '.' + arr[1]
            }else{
                value = value.slice(0,value.includes('-')?(bit+1):bit)
            }
            if(value < min){
                value = min
            }
            if(value > max){
                value = max
            }
            return value
        }
    }
}
</script>

<style scoped>
.box-container{
    position: relative;
    display: inline-block;
}
.transfer-input{
    position: absolute;
    top: 0;
    right: 0;
}
.btn-box{
    position: relative;
    right: 1px;
    top: 1px;
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
}
.btn-box span{
    width: 40px;
    height: 19px;
    display: flex;
    align-items: center;
    background: #F5F7FA;
    justify-content: center;
    border: 1px solid #DCDFE6;
    color: #606266;
    font-size: 10px;
    box-sizing: border-box;
    cursor: pointer;
}
.btn-box span:nth-child(1){
    border-top-right-radius: 4px;
    border-top: none;
    border-right: none;
}
.btn-box span:nth-child(2){
    border-bottom-right-radius: 4px;
    border-bottom: none;
    border-top: none;
    border-right: none;
}
.input-number{
    font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif !important;
    font-size: 14px;
    height: 40px;
    text-align: center;
    color: #606266;
    text-indent: 0;
}
.input-number:focus{
    outline: none;
}
.input-border{
    border-radius: 4px;
    border: 1px solid #DCDFE6;
}
.input-border:hover{
    border: 1px solid #C0C4CC;
}
.input-border:focus{
    border-radius: 4px;
    border: 1px solid #409EFF;
}
.btn-box .disable-btn{
    color: #DCDFE6;
}
.disable-btn{
    cursor: no-drop!important;
}


input::-webkit-input-placeholder { /* WebKit, Blink, Edge */
    color:    #C0C4CC;
}
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
   color:    #C0C4CC;
}
::-moz-placeholder { /* Mozilla Firefox 19+ */
   color:    #C0C4CC;
}
input:-ms-input-placeholder { /* Internet Explorer 10-11 */
   color:   #C0C4CC;
}
input::-ms-input-placeholder { /* Microsoft Edge */
   color:    #C0C4CC;
}

.suffix-box-bg{
    background-color: #f5f7fa;
}
.suffix-box{
    width: 40px;
    text-align: center;
}
</style>